package com.dream.libsoundtouch;

/**
 * SoundTouch 音频变速处理，该库要求采样Bit为16位
 */
public class SoundTouch {

    static {
        System.loadLibrary("soundtouch");
    }

    private native void nativeInit();
    private native void nativeSetSampleRate(int sampleRate);
    private native void nativeSetChannels(int channels);
    private native void nativeSetTempoChange(float tempo);
    private native void nativeSetPitchSemiTones(int pitch);
    private native void nativeSetRateChange(float rate);
    private native void nativePutSamples(short[] samples, int len);
    private native int nativeReceiveSamples(short[] buffer, int bufferSize);
    private native void nativeFlush();
    private native void nativeClear();

    public SoundTouch() {
        nativeInit();
    }

    /**
     * 设置采样率，单位为Hz，如8000、16000、44100
     * @param sampleRate
     */
    public void setSampleRate(int sampleRate) {
        nativeSetSampleRate(sampleRate);
    }

    /**
     * 通道数，1为单声道，2为双声道
     * @param channels
     */
    public void setChannels(int channels) {
        nativeSetChannels(channels);
    }

    /**
     * 音频变速处理， 1为不变速，大于1为变快，小于1为变慢
     * 主要影响音频的节奏，对音高的影响相对较小。它可以在不改变音高的情况下加快或减慢音频的节奏。
     * 但主要原理是控制节奏，并不能严格时间时长控制，比如设置2，并不能确保时长是原来的一半，但听感上是二倍速播放
     * @param tempo
     */
    public void setTempoChange(float tempo) {
        nativeSetTempoChange(tempo);
    }

    /**
     * 音调控制
     * 当参数为 1.0 时，表示保持原始音高不变。如果设置为大于 1.0 的值，会使音频的音高升高，听起来更加尖锐；如果设置为小于 1.0 的值，会使音频的音高降低，听起来更加低沉。
     * @param pitch
     */
    public void setPitchSemiTones(int pitch) {
        nativeSetPitchSemiTones(pitch);
    }

    /**
     * 设置变速倍率，1为不变速，小于1为变快，大于1为变慢, 如0.5为变慢一倍，2为变快一倍
     * 这种方式可以实现变速，可以严格控制时长，但是会有明显的音高变化
     * 如果不需要严格的时长控制，建议用setTempoChange方法，会有更平滑的音高变化，可以实现变速不变调
     * @param rate
     */
    public void setRateChange(float rate) {
        nativeSetRateChange(rate);
    }

    /**
     * 写入数据进行转换
     * @param samples
     * @param len
     */
    public void putSamples(short[] samples, int len) {
        nativePutSamples(samples, len);
    }

    /**
     * 读取转换后的数据
     * @param buffer
     * @param bufferSize
     * @return 实际有效的数据大小
     */
    public int receiveSamples(short[] buffer, int bufferSize) {
        return nativeReceiveSamples(buffer, bufferSize);
    }

    public void flush() {
        nativeFlush();
    }

    public void clear() {
        nativeClear();
    }
}
